import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileWriter;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

@SuppressWarnings("serial")
public class MyUI extends JFrame
{
	private JTextField my_text_url = new JTextField();
	
	private JButton my_go_button 				= new JButton("INITIATE CRAWL!");
	private JLabel my_output_text 				= new JLabel();
	private MultiThreadEnv my_multithread_env 	= new MultiThreadEnv();
	
	private JLabel programTypeLabel 		= new JLabel("Program Run-Type:");
	private JLabel webThreadsLabel 			= new JLabel("Number of Web Threads:");
	private JLabel parserThreadsLabel 		= new JLabel("Number of Parser Threads:");
	private JLabel analyzerThreadsLabel 	= new JLabel("Number of Analyzer Threads:");
	private JLabel maxPagesLabel 			= new JLabel("Maximum Page Limit:");
	private JLabel websiteLabel 			= new JLabel("Enter full website:");
	private JLabel keywordLabel 			= new JLabel("Enter keyword:");
	
	//single/multi thread radio buttons---------------------------
	private JRadioButton singleThreadBtn 	= new JRadioButton("Single-Threaded");
	private JRadioButton multiThreadBtn 	= new JRadioButton("Multi-Threaded");
	
	private JComboBox numWebThreads 		= new JComboBox();
	private JComboBox numParserThreads 		= new JComboBox();
	private JComboBox numAnalyzerThreads 	= new JComboBox();
	private JComboBox pageLimit 			= new JComboBox();
	
	//keyword add/remove buttons and text field/list--------------
	private JList keywordList;
	private DefaultListModel listModel 	= new DefaultListModel();
	private JTextField keywordText 		= new JTextField();
	private JButton keywordAddButton 	= new JButton("ADD");
	private JButton keywordRemoveButton = new JButton("REMOVE");
	
	private JScrollPane areaScrollPane = new JScrollPane(my_output_text);
	private JScrollPane keywordScroller;
	
	private JPanel runPanel 			= new JPanel();
	private JPanel threadPanel 			= new JPanel();
	private JPanel configurationPanel 	= new JPanel();
	private JPanel buttonPanel 			= new JPanel();
	
	private StringBuilder output = new StringBuilder();
	
	public MyUI()
	{
		my_output_text.setSize(new Dimension(200,200));
		areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		areaScrollPane.getVerticalScrollBar().setUnitIncrement(60);
		areaScrollPane.getVerticalScrollBar().setBlockIncrement(180);
		
		Integer[] threadCount = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
		for(int i = 0; i < threadCount.length; i++)
		{
			numWebThreads.addItem(threadCount[i]);
			numParserThreads.addItem(threadCount[i]);
			numAnalyzerThreads.addItem(threadCount[i]);	
		}
		
		Integer[] pageLimitValues = {50, 100, 150, 200, 250, 500, 1000, 5000, 10000};
		for(int i = 0; i < pageLimitValues.length; i++)
		{
			pageLimit.addItem(pageLimitValues[i]);
		}
		pageLimit.setEditable(true);
		
		setTitle("Spider");
		setSize(800,400);
		this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setupGUI();
		my_multithread_env.my_gui_env = this;
	}
	
	private void centerGUI()
	{
		// Get the size of the screen
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		
		// Determine the new location of the window for it to be centered
		int w = this.getSize().width;
		int h = this.getSize().height;
		int x = (dim.width/2) - (w/2);
		int y = (dim.height/2)- (h/2);
		 
		// Move the window to centered position
		this.setLocation(x, y);
	}
	
	private boolean alreadyInList(String keyword)
	{
		return listModel.contains(keyword.toLowerCase());
	}
	
	private void setupGUI()
	{
		centerGUI();
		
		runPanel.setLayout(new 				BoxLayout(runPanel, BoxLayout.LINE_AXIS));
		threadPanel.setLayout(new 			BoxLayout(threadPanel, BoxLayout.Y_AXIS));
		configurationPanel.setLayout(new 	BoxLayout(configurationPanel, BoxLayout.Y_AXIS));
		buttonPanel.setLayout(new 			BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
		
		//single/multi thread label---------------
		programTypeLabel.setLabelFor(multiThreadBtn);
		programTypeLabel.setAlignmentX(RIGHT_ALIGNMENT);
		configurationPanel.add(programTypeLabel);
		
		//single/multi thread radio buttons-------
		ButtonGroup group = new ButtonGroup();
		singleThreadBtn.setAlignmentX(CENTER_ALIGNMENT);
		group.add(singleThreadBtn);
		singleThreadBtn.setSelected(true);
		multiThreadBtn.setAlignmentX(CENTER_ALIGNMENT);
		group.add(multiThreadBtn);
		
		configurationPanel.add(singleThreadBtn);
		configurationPanel.add(multiThreadBtn);
		configurationPanel.add(Box.createRigidArea(new Dimension(100, 10)));
		
		//number of threads labels----------------
		webThreadsLabel.setLabelFor(numWebThreads);
		webThreadsLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
		threadPanel.add(webThreadsLabel);
		threadPanel.add(numWebThreads);
		threadPanel.add(Box.createRigidArea(new Dimension(100, 10)));
		parserThreadsLabel.setLabelFor(numParserThreads);
		parserThreadsLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
		threadPanel.add(parserThreadsLabel);
		threadPanel.add(numParserThreads);
		threadPanel.add(Box.createRigidArea(new Dimension(100, 10)));
		analyzerThreadsLabel.setLabelFor(numParserThreads);
		analyzerThreadsLabel.setAlignmentX(Component.RIGHT_ALIGNMENT);
		threadPanel.add(analyzerThreadsLabel);
		threadPanel.add(numAnalyzerThreads);
		
		//page limit drop down--------------------
		maxPagesLabel.setLabelFor(pageLimit);
		maxPagesLabel.setAlignmentX(RIGHT_ALIGNMENT);
		configurationPanel.add(maxPagesLabel);
		configurationPanel.add(pageLimit);
		
		//keyword list----------------------------
		keywordList 	= new JList(listModel);
		keywordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		keywordScroller = new JScrollPane(keywordList);
		keywordScroller.setPreferredSize(new Dimension(100, 100));
		
		keywordLabel.setLabelFor(keywordText);
		
		configurationPanel.add(Box.createRigidArea(new Dimension(100, 10)));
		keywordLabel.setAlignmentX(RIGHT_ALIGNMENT);
		configurationPanel.add(keywordLabel);
		keywordText.setMaximumSize(new Dimension(250, 100));
		
		configurationPanel.add(keywordText);
		
		buttonPanel.add(Box.createHorizontalGlue());
		buttonPanel.add(keywordAddButton);
		buttonPanel.add(keywordRemoveButton);
		buttonPanel.add(Box.createHorizontalGlue());
		configurationPanel.add(buttonPanel);
		configurationPanel.add(Box.createRigidArea(new Dimension(100, 10)));
		
		configurationPanel.add(keywordScroller);
		
		//url text box----------------------------
		websiteLabel.setLabelFor(my_text_url);
		runPanel.add(websiteLabel);
		runPanel.add(my_text_url);
		runPanel.add(my_go_button);
		
		keywordAddButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				String keyword = keywordText.getText().toLowerCase();
				
				if(keyword.equals("") || alreadyInList(keyword) || listModel.getSize() == 10)
				{
					keywordText.requestFocusInWindow();
					keywordText.selectAll();
					return;
				}
			
				int size = listModel.getSize();
				
				listModel.addElement(keywordText.getText().toLowerCase());
				//Select the new item and make it visible.
	            keywordList.setSelectedIndex(size);
	            keywordList.ensureIndexIsVisible(size);
	            
	            keywordRemoveButton.setEnabled(true);
	            
				keywordText.requestFocusInWindow();
				keywordText.setText("");
			}
		});
		
		keywordRemoveButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				int index 	= keywordList.getSelectedIndex();
				listModel.remove(index);
				
				int size 	= listModel.getSize();
				
				if(size == 0)
				{
					keywordRemoveButton.setEnabled(false);
				}
				else
				{
					if(index == listModel.getSize())
					{
						index--;
					}
					
					keywordList.setSelectedIndex(index);
					keywordList.ensureIndexIsVisible(index);
				}
			}
		});
		
		//actionListener for go button------------
		my_go_button.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent arg0)
			{
				if(singleThreadBtn.isSelected())
				{
					my_multithread_env.setMultiOrSingleThread(MultiThreadEnv.ThreadTypes.SINGLETHREAD);
				}
				else
				{
					my_multithread_env.setMultiOrSingleThread(MultiThreadEnv.ThreadTypes.MULTITHREAD);
				}

				for(int i = 0; i < listModel.getSize(); i++)
				{
					my_multithread_env.addKeyword(listModel.get(i).toString());
				}
				my_multithread_env.addKeyword("intelligence");
				my_multithread_env.addKeyword("artificial");
				my_multithread_env.addKeyword("agent");
				my_multithread_env.addKeyword("university");
				my_multithread_env.addKeyword("research");
				my_multithread_env.addKeyword("science");
				my_multithread_env.addKeyword("robot");
				
				my_multithread_env.setAllowedWebThreads((Integer)numWebThreads.getSelectedItem());
				my_multithread_env.setAllowedParserThreads((Integer)numParserThreads.getSelectedItem());
				my_multithread_env.setAllowedAnalyzerThreads((Integer)numAnalyzerThreads.getSelectedItem());
				
				my_multithread_env.setPageLimit((Integer)pageLimit.getSelectedItem());
				
				if ((!my_text_url.getText().toLowerCase().startsWith("http://")))
				{
					StringBuilder text_helper = new StringBuilder("http://");
					text_helper.append(my_text_url.getText());
					my_multithread_env.takeInputURL(text_helper.toString());
				}
				else
				{
					my_multithread_env.takeInputURL(my_text_url.getText().toLowerCase());	
				}
			}
		});
		
		keywordRemoveButton.setEnabled(false);
		
		this.add(configurationPanel, BorderLayout.LINE_START);
		//this.add(keywordPanel, BorderLayout.PAGE_START);
		this.add(threadPanel, BorderLayout.LINE_END);
		this.add(runPanel, BorderLayout.PAGE_END);
		
		this.add(areaScrollPane, BorderLayout.CENTER);
		
		setVisible(true);
	}
	
	public void setOutputText(String the_output)
	{
		output.append(the_output);
		my_output_text.setText(output.toString());

		try
		{
			FileWriter out = new FileWriter("spiderRunST1.txt");
			out.write(output.toString());
			out.close();
		}
		catch(Exception e)
		{
			System.out.println("IO EXECPTION");
		}
	}
	
	public static void main(String... strings)
	{
		new MyUI();
	}
}
